package com.fzy.core.acegi;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.apache.log4j.Logger;

import com.fzy.core.acegi.provider.MyUsernamePasswordAuthenticationToken;

public class MyAuthenticationProcessingFilter extends
		AuthenticationProcessingFilter {
	protected final Logger log = Logger.getLogger(getClass());
	
	public static final String ACEGI_SECURITY_FORM_USERFLAG_KEY = "j_userflag";
	private String defaultConsoleUrl;
	private String defaultFrontUrl;
	
	private String authenticationInsideFailureUrl;
	private String authenticationOutSideFailureUrl;
	
	
	/*JdbcDao jdbcDao;

	public JdbcDao getJdbcDao() {
		return jdbcDao;
	}

	public void setJdbcDao(JdbcDao jdbcDao) {
		this.jdbcDao = jdbcDao;
	}*/
	
	public Authentication attemptAuthentication(HttpServletRequest request)
        throws AuthenticationException {
        String username = obtainUsername(request);
        String password = obtainPassword(request);
        String userFlag = obtainUserFlag(request);

        if (username == null) {
            username = "";
        }

        if (password == null) {
            password = "";
        }

        UsernamePasswordAuthenticationToken authRequest = new MyUsernamePasswordAuthenticationToken(username, password,userFlag);

        // Place the last username attempted into HttpSession for views
        request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username);

        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);

        return this.getAuthenticationManager().authenticate(authRequest);
	}
	
	
	
	protected void successfulAuthentication(HttpServletRequest request,
			HttpServletResponse response, Authentication authResult)
			throws IOException {
		if (log.isDebugEnabled()) {
			log.debug("Authentication success: " + authResult.toString());
		}

		SecurityContextHolder.getContext().setAuthentication(authResult);

		if (log.isDebugEnabled()) {
			log
					.debug("Updated SecurityContextHolder to contain the following Authentication: '"
							+ authResult + "'");
		}

		// Don't attempt to obtain the url from the saved request if
		// alwaysUsedefaultTargetUrl is set
		String targetUrl = false ? null : obtainFullRequestUrl(request);

		if (targetUrl == null) {
			boolean isConsoleUser = true;
			GrantedAuthority[] gas = authResult.getAuthorities();
			for (int i = 0; i < gas.length; i++) {
				GrantedAuthority g = gas[i];
				//System.out.println(g.getAuthority());
				if(g == null) continue;
				if("ru_passport".equals(g.getAuthority().toLowerCase())){
					isConsoleUser = false;
					break;
				}
			}
			
			targetUrl = isConsoleUser ? getDefaultConsoleUrl() : getDefaultFrontUrl();
		}

		if (log.isDebugEnabled()) {
			log
					.debug("Redirecting to target URL from HTTP Session (or default): "
							+ targetUrl);
		}

		onSuccessfulAuthentication(request, response, authResult);

		getRememberMeServices().loginSuccess(request, response, authResult);
		String target_url = request.getServletPath();
//		if("/j_acegi_security_check".equals(target_url)){
//		//添加首页提醒
//			Long userid = CommonUtils.getCurrentUserId();
//			List list = jdbcDao.getJdbcTemplate().queryForList("select * from sk_apply_base where created_user = "+String.valueOf(userid));
//			if(list!=null&&list.size()>0){
//				request.getSession().setAttribute("msg_mark", " 你目前已创建了 "+String.valueOf(list.size())+" 条申请，进入已申请信息查询页面查看");
//			}
//		}
		// Fire event
		if (this.eventPublisher != null) {
			eventPublisher
					.publishEvent(new InteractiveAuthenticationSuccessEvent(
							authResult, this.getClass()));
		}
		sendRedirect(request, response, targetUrl);
	}
	
	 protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException failed) throws IOException {
        SecurityContextHolder.getContext().setAuthentication(null);

        if (logger.isDebugEnabled()) {
            logger.debug("Updated SecurityContextHolder to contain null Authentication");
        }
        
        String flag=request.getParameter(ACEGI_SECURITY_FORM_USERFLAG_KEY);
        String failureUrl="1".equals(flag)?authenticationOutSideFailureUrl:authenticationInsideFailureUrl;
                	
        //failureUrl = getExceptionMappings().getProperty(failed.getClass().getName(), authenticationConsoleFailureUrl);

        if (logger.isDebugEnabled()) {
            logger.debug("Authentication request failed: " + failed.toString());
        }

        try {
            request.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed);
        } catch (Exception ignored) {}

        onUnsuccessfulAuthentication(request, response, failed);

        getRememberMeServices().loginFail(request, response);

        sendRedirect(request, response, failureUrl);
    }	 
	 
	protected String obtainUserFlag(HttpServletRequest request) {
	      return request.getParameter(ACEGI_SECURITY_FORM_USERFLAG_KEY);
	}

	public String getDefaultConsoleUrl() {
		return defaultConsoleUrl;
	}

	public void setDefaultConsoleUrl(String defaultConsoleUrl) {
		this.defaultConsoleUrl = defaultConsoleUrl;
	}

	public String getDefaultFrontUrl() {
		return defaultFrontUrl;
	}

	public void setDefaultFrontUrl(String defaultFrontUrl) {
		this.defaultFrontUrl = defaultFrontUrl;
	}

	public String getAuthenticationInsideFailureUrl() {
		return authenticationInsideFailureUrl;
	}

	public void setAuthenticationInsideFailureUrl(
			String authenticationInsideFailureUrl) {
		this.authenticationInsideFailureUrl = authenticationInsideFailureUrl;
	}
	
	public String getAuthenticationOutSideFailureUrl() {
		return authenticationOutSideFailureUrl;
	}

	public void setAuthenticationOutSideFailureUrl(String authenticationOutSideFailureUrl) {
		this.authenticationOutSideFailureUrl = authenticationOutSideFailureUrl;
	}
}
